package pl.pw.gis.gc_sa.tests;

import java.util.Vector;

import org.junit.BeforeClass;
import org.junit.Test;

import pl.pw.gis.gc_sa.algo.SimulatedAnnealing;
import pl.pw.gis.gc_sa.data.Graph;
import pl.pw.gis.gc_sa.utils.Utils;

/**
 * Klasa zawierajaca testy wykonywane przy pomocy biblioteki jUnit.
 * 
 * W tej klasie testowany jest wplyw wyboru parametrow algorytmu symulowanego
 * wyzarzania na jakosc wynikow. Test przeprowadzono poprzez zmienianie po
 * jednym parametrze z temperatury startowej, temperatury minimalnej, czynnika
 * chlodzacego oraz liczby wewnetrznych iteracji w jednym tescie.
 * 
 * @author Lukasz
 * 
 */
public class SimulatedAnnealingParamsTest {
    private static final long MILLIS_LIMIT_PER_RUN = 300000;
    private static final float DEF_START_TEMP = 100;
    private static final float DEF_TEMP_DIFF = 0.95f;
    private static final float DEF_TEMP_MIN = 0.0001f;
    private static final int DEF_ITER_MAX = SimulatedAnnealing.USE_NO_VERTICES_AS_ITER_MAX;

    private static final float[] startTemps = { 10, 50, 100, 200 };
    private static final float[] tempDiffs = { 0.5f, 0.9f, 0.95f, 0.99f };
    private static final float[] tempMins = { 0.01f, 0.001f, 0.0005f, 0.0001f,
            0.00001f };
    private static final int[] iterMaxs = {
            SimulatedAnnealing.USE_SQRT_NO_VERTICES_AS_ITER_MAX,
            SimulatedAnnealing.USE_HALF_NO_VERTICES_AS_ITER_MAX,
            SimulatedAnnealing.USE_NO_VERTICES_AS_ITER_MAX,
            SimulatedAnnealing.USE_NO_VERTICES_X2_AS_ITER_MAX };

    private static Vector<Graph> graphs;

    @BeforeClass
    public static void setUp() throws Exception {
        graphs = new Vector<Graph>();

        graphs.add(Graph.createVPGraph(10, 0.5f));
        graphs.add(Graph.createVPGraph(50, 0.5f));
        graphs.add(Graph.createVPGraph(100, 0.5f));
        graphs.add(Graph.createVPGraph(200, 0.5f));
        graphs.add(Graph.createVPGraph(300, 0.5f));
        graphs.add(Graph.createVPGraph(500, 0.5f));
    }

    @Test
    public void testStartTemp() throws Exception {
        Utils.log("Starting startTemp tests\n---------------------------");
        long start = System.currentTimeMillis();

        for (Graph graph : graphs) {
            Utils.log("--------------------------------");
            Utils.log("Testing " + graph.getGraphInfo());

            for (float f : startTemps) {
                SimulatedAnnealing sa = new SimulatedAnnealing(graph,
                        DEF_TEMP_MIN, f, DEF_TEMP_DIFF, DEF_ITER_MAX);
                sa.start();
                sa.join(MILLIS_LIMIT_PER_RUN);
                Utils.log(sa.getMethodParameters());
                Utils.log(sa.getMethodOutcome());
            }
        }
        Utils.log("Test took " + (System.currentTimeMillis() - start) + "\n");
    }

    @Test
    public void testTempDiff() throws InterruptedException {
        Utils.log("Starting tempDiffs tests\n---------------------------");
        long start = System.currentTimeMillis();

        for (Graph graph : graphs) {
            Utils.log("--------------------------------");
            Utils.log("Testing " + graph.getGraphInfo());

            for (float f : tempDiffs) {
                SimulatedAnnealing sa = new SimulatedAnnealing(graph,
                        DEF_TEMP_MIN, DEF_START_TEMP, f, DEF_ITER_MAX);
                sa.start();
                sa.join(MILLIS_LIMIT_PER_RUN);
                Utils.log(sa.getMethodParameters());
                Utils.log(sa.getMethodOutcome());
            }
        }
        Utils.log("Test took " + (System.currentTimeMillis() - start) + "\n");
    }

    @Test
    public void testTempMin() throws Exception {
        Utils.log("Starting startTemp tests\n---------------------------");
        long start = System.currentTimeMillis();

        for (Graph graph : graphs) {
            Utils.log("--------------------------------");
            Utils.log("Testing " + graph.getGraphInfo());

            for (float f : tempMins) {
                SimulatedAnnealing sa = new SimulatedAnnealing(graph, f,
                        DEF_START_TEMP, DEF_TEMP_DIFF, DEF_ITER_MAX);
                sa.start();
                sa.join(MILLIS_LIMIT_PER_RUN);
                Utils.log(sa.getMethodParameters());
                Utils.log(sa.getMethodOutcome());
            }
        }
        Utils.log("Test took " + (System.currentTimeMillis() - start) + "\n");
    }

    @Test
    public void testIterMax() throws Exception {
        Utils.log("Starting iterMax tests\n---------------------------");
        long start = System.currentTimeMillis();

        for (Graph graph : graphs) {
            Utils.log("--------------------------------");
            Utils.log("Testing " + graph.getGraphInfo());

            for (int i : iterMaxs) {
                SimulatedAnnealing sa = new SimulatedAnnealing(graph,
                        DEF_TEMP_MIN, DEF_START_TEMP, DEF_TEMP_DIFF, i);
                sa.start();
                sa.join(MILLIS_LIMIT_PER_RUN);
                Utils.log(sa.getMethodParameters());
                Utils.log(sa.getMethodOutcome());
            }
        }
        Utils.log("Test took " + (System.currentTimeMillis() - start));
    }
}
